'''
多人聊天室 客户端
'''
#coding:uft-8
import wx # wxPython
import threading
from socket import socket,AF_INET,SOCK_STREAM
class SjClient(wx.Frame):
    def __init__(self,client_name):
        
        # ----------------界面绘制开始---------------
        '''
        id 界面编号
        title 标题
        pos 位置
        size 窗体大小 单位像素
        '''
        wx.Frame.__init__(self,None,id = 1001,title=client_name+'的客户端界面',pos=wx.DefaultPosition,size=(400,550))
        # 创建面板对象
        pl = wx.Panel(self)
        # 面板里套盒子
        box = wx.BoxSizer(wx.VERTICAL) # 垂直布局

        fg = wx.FlexGridSizer(wx.HSCROLL) # flex弹性盒子布局
        # 按钮
        conn_btn = wx.Button(pl,size=(200,40),label="连接")
        dis_conn_btn = wx.Button(pl,size=(200,40),label="断开")
        # 放到弹性盒子
        fg.Add(conn_btn,1,wx.TOP|wx.LEFT)
        fg.Add(dis_conn_btn)
        # 弹性盒子放到box
        box.Add(fg,1,wx.ALIGN_CENTER)

        # 只读聊天框
        self.show_text=wx.TextCtrl(pl,size=(400,210),style=wx.TE_MULTILINE|wx.TE_READONLY)
        box.Add(self.show_text,1,wx.ALIGN_CENTER)
        # 聊天输入框
        self.chat_text=wx.TextCtrl(pl,size=(400,180),style=wx.TE_MULTILINE)
        box.Add(self.chat_text,1,wx.ALIGN_CENTER)

        # 底部
        fg2 = wx.FlexGridSizer(wx.HSCROLL) # flex弹性盒子布局
        # 按钮
        reset_btn = wx.Button(pl,size=(200,40),label="重置")
        send_btn = wx.Button(pl,size=(200,40),label="发送")
        # 放到弹性盒子
        fg2.Add(reset_btn,1,wx.TOP|wx.LEFT)
        fg2.Add(send_btn)
        # 弹性盒子放到box
        box.Add(fg2,1,wx.ALIGN_CENTER)

        # 盒子放到面板
        pl.SetSizer(box)

        # ----------------界面绘制结束---------------

        # ---------------- 客户端功能开始-----------------
        # 绑定连接事件
        self.Bind(wx.EVT_BUTTON,self.connect_to_server,conn_btn)
        # 绑定发送事件
        self.Bind(wx.EVT_BUTTON,self.send_to_server,send_btn)
        # 绑定重置事件
        self.Bind(wx.EVT_BUTTON,self.reset,reset_btn)
        # 绑定断开事件
        self.Bind(wx.EVT_BUTTON,self._disconnect_server,dis_conn_btn)

        # 属性
        self.client_name = client_name # 客户端名称
        self.isConnected = False # 连接成功标识
        self.client_socket = None  # 客户端socket

    # 点击连接事件
    def connect_to_server(self,event):
        if not self.isConnected:
            server_host_port = ('127.0.0.1',8888)
            self.client_socket = socket(AF_INET,SOCK_STREAM)
            self.client_socket.connect(server_host_port)
            self.client_socket.send(self.client_name.encode('utf-8')) # 第一次连接 发送客户端名称
        
            self.isConnected = True
            print(f"{self.client_name}连接到服务端成功")
            # 启动一个客户端线程，与服务端会话线程会话
            client_thread = threading.Thread(target=self.recv_data)
            client_thread.daemon = True
            client_thread.start()
    
    # 点击发送事件
    def send_to_server(self,e):
        try:
            text = self.chat_text.GetValue()
            if text != '' and self.isConnected:
                self.client_socket.send(text.encode('utf-8'))
                self.chat_text.SetValue('')
        except Exception as e:
            print(f"发送错误: {e}")
            self.isConnected = False

    # 点击重置事件
    def reset(self,e):
        self.chat_text.Clear()
    # 点击断开连接
    def _disconnect_server(self,e):
        self.client_socket.send('S-going_to_disconnect-J'.encode('utf-8'))
        self.isConnected = False
    # 接收服务端数据
    def recv_data(self):
        
        while self.isConnected:
            # 接收来自服务端的数据
            data = self.client_socket.recv(1024).decode('utf-8')  
            print("接收到来自服务端消息：",data)  
            # 只读文本框展示
            self.show_text.AppendText('-'*40+'\n'+data+'\n')

if __name__ == '__main__':
    app = wx.App()
    client_name = input("请输入客户端名称：")
    client = SjClient(client_name)
    client.Show()
    app.MainLoop() # 循环刷新显示